import JNSocket from "../../../../extensions/ngame/assets/ngame/network/JNSocket";
import { JNSyncAction } from "../../../../extensions/ngame/assets/ngame/sync/JNSyncAction";
import { JNSyncMessage } from "../../../../extensions/ngame/assets/ngame/sync/JNSyncMessage";
import JNSyncFrame, { JNFrameInfo, JNFrameInfos, JNFrameInputs } from "../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
import JNSyncFrameComponent from "../../../../extensions/ngame/assets/ngame/sync/frame/game/JNSyncFrameComponent";
import JNSyncFrameProtoComponent from "../../../../extensions/ngame/assets/ngame/sync/frame/game/JNSyncFrameProtoComponent";
import JNLayer, { JNLayerAnim, JNLayerInfo } from "../../../../extensions/ngame/assets/ngame/ui/JNLayer";
import JNLayerBase from "../../../../extensions/ngame/assets/ngame/ui/base/JNLayerBase";
import { EventDispatcher } from "../../../../extensions/ngame/assets/ngame/util/EventDispatcher";
import NGameMessage from "../../../../extensions/ngame/assets/ngame/util/NGameMessage";
import axios from "../../../../extensions/ngame/assets/plugins/axios.js";

export enum GUI{
    ViewDemo = "ViewDemo",
}

export enum GLayer{
    View = "View",
}

//重写UI
class JNGLayer extends JNLayer{
    layers: string[] = [GLayer.View];
    views: { [key: string]: JNLayerInfo; } = {
        [GUI.ViewDemo]:{ layer:GLayer.View,uri:"UIDemo/ViewDemo",anims:{front:JNLayerAnim.BackOutOpen,back:JNLayerAnim.BackInClose} }
    };
}

//重写Socket
class JNGSocket extends JNSocket{
    public url() {
        return "ws://192.168.0.127:8080/websocket";
    }
}

//重写帧同步
class JNGSyncFrame extends JNSyncFrame{

    async onServerData(start?:number,end?:number): Promise<JNFrameInfos> {

        return app.proto
                .getType(JNSyncMessage.JNFrameInfos)
                .decode(
                    new Uint8Array(

                        (await app.api.get("/sync/frame",{
                            responseType:'arraybuffer',
                            params:{
                                start,
                                end
                            }
                        })).data
                    )
                ) as any;

    }

    onSendInput(message: JNFrameInputs) {
        app.socket.Send(JNSyncAction.NSyncFrameInput,message,JNSyncMessage.JNFrameInputs);
    }

}

export const app = {
    layer : new JNGLayer(),
    socket : new JNGSocket(),
    sync : new JNGSyncFrame(),
    event : EventDispatcher.getIns(),
    proto : NGameMessage.getIns(),
    api : axios.create({
        baseURL: "http://192.168.0.127:8080",
    }),
}

//重写UI Base
export class JNGLayerBase extends JNLayerBase{
    public close():void {
        console.log("close");
        app.layer.CloseNode(this.node);
    }
}

//重写Sync Base
export class JNGSyncBase<T> extends JNSyncFrameComponent<T>{
    onSyncUpdate(dt: number,frame:JNFrameInfo, input?: T) { }
    protected getSync(): JNSyncFrame {
        return app.sync
    }

}
//重写Sync Proto Base
export abstract class JNGSyncProtoBase<T> extends JNSyncFrameProtoComponent<T>{

    onSyncUpdate(dt: number,frame:JNFrameInfo, input?: T) { }
    protected getSync(): JNSyncFrame {
        return app.sync
    }

}
